export interface DayForecast {
  date: string;
  temperature: {
    min: number;
    max: number;
  };
  condition: string;
  humidity: number;
  windSpeed: number;
  icon: string;
}

export interface WeatherData {
  city: string;
  forecast: DayForecast[];
  apiSource?: string;
}

interface OpenWeatherForecastItem {
  dt: number;
  main: {
    temp: number;
    feels_like: number;
    temp_min: number;
    temp_max: number;
    pressure: number;
    sea_level: number;
    grnd_level: number;
    humidity: number;
    temp_kf: number;
  };
  weather: Array<{
    id: number;
    main: string;
    description: string;
    icon: string;
  }>;
  clouds: {
    all: number;
  };
  wind: {
    speed: number;
    deg: number;
    gust: number;
  };
  visibility: number;
  pop: number;
  sys: {
    pod: string;
  };
  dt_txt: string;
}

interface OpenWeatherResponse {
  cod: string;
  message: number;
  cnt: number;
  list: OpenWeatherForecastItem[];
  city: {
    id: number;
    name: string;
    coord: {
      lat: number;
      lon: number;
    };
    country: string;
    population: number;
    timezone: number;
    sunrise: number;
    sunset: number;
  };
}

// 如果API请求失败，使用模拟数据
function generateMockWeatherData(city: string): WeatherData {
  const today = new Date();
  const forecast: DayForecast[] = Array.from({ length: 5 }).map((_, index) => {
    const date = new Date(today);
    date.setDate(today.getDate() + index);

    // 使用城市名称的哈希值来生成伪随机但一致的天气数据
    const dayHash = hashCode(date.toISOString() + city);
    const conditions = ["晴天", "多云", "阴天", "小雨", "雷雨"];
    const icons = ["01d", "02d", "03d", "10d", "11d"];
    const conditionIndex = Math.abs(dayHash % conditions.length);

    // 根据城市和日期生成温度
    const baseTemp = 15 + Math.abs(hashCode(city) % 15);
    const variance = Math.abs(dayHash % 10);

    return {
      date: date.toISOString().split("T")[0],
      temperature: {
        min: baseTemp - variance / 2,
        max: baseTemp + variance,
      },
      condition: conditions[conditionIndex],
      humidity: 50 + Math.abs(dayHash % 40),
      windSpeed: 5 + Math.abs(dayHash % 20),
      icon: icons[conditionIndex],
    };
  });

  return {
    city,
    forecast,
  };
}

// 简单的字符串哈希函数，用于生成伪随机但一致的数据
function hashCode(str: string): number {
  let hash = 0;
  for (let i = 0; i < str.length; i++) {
    const char = str.charCodeAt(i);
    hash = (hash << 5) - hash + char;
    hash = hash & hash; // Convert to 32bit integer
  }
  return hash;
}

export async function fetchWeatherData(
  city: string,
  userApiKey?: string
): Promise<WeatherData> {
  try {
    const apiKey = userApiKey || process.env.NEXT_PUBLIC_OPENWEATHER_API_KEY;

    if (!apiKey) {
      console.error("OpenWeather API key is not defined");
      throw new Error("API密钥未配置，请在设置页面配置您的API密钥");
    }

    console.log(
      "Using API key:",
      apiKey.substring(0, 3) + "..." + apiKey.substring(apiKey.length - 3)
    );

    // 第一步：获取经纬度
    const geoRes = await fetch(
      `https://api.openweathermap.org/geo/1.0/direct?q=${encodeURIComponent(
        city
      )}&limit=1&appid=${apiKey}`
    );

    const geoData = await geoRes.json();
    if (!geoRes.ok || !geoData || geoData.length === 0) {
      throw new Error(`找不到城市"${city}"，请检查城市名称`);
    }

    const { lat, lon, name } = geoData[0];

    // 第二步：获取 5 天 / 3 小时天气预报
    const weatherRes = await fetch(
      `https://api.openweathermap.org/data/2.5/forecast?lat=${lat}&lon=${lon}&units=metric&appid=${apiKey}&lang=zh_cn`,
      { cache: "no-store" }
    );

    if (!weatherRes.ok) {
      const errorData = await weatherRes.json().catch(() => ({}));
      console.error("OpenWeather API error response:", {
        status: weatherRes.status,
        statusText: weatherRes.statusText,
        data: errorData,
      });

      if (weatherRes.status === 401) {
        throw new Error("API密钥无效或未激活，请检查API密钥设置");
      } else if (weatherRes.status === 429) {
        throw new Error("API请求次数超过限制，请稍后再试");
      } else {
        throw new Error(
          `OpenWeather API错误: ${weatherRes.status} ${weatherRes.statusText}`
        );
      }
    }

    const data: OpenWeatherResponse = await weatherRes.json();
    const dailyForecasts = processForecastData(data);

    return {
      city: name,
      forecast: dailyForecasts,
      apiSource: "openweather",
    };
  } catch (error) {
    console.error("Error fetching weather data:", error);
    console.log("Falling back to mock data for city:", city);
    return generateMockWeatherData(city);
  }
}

function processForecastData(data: OpenWeatherResponse): DayForecast[] {
  // 按日期分组
  const forecastsByDay: Record<string, OpenWeatherForecastItem[]> = {};

  data.list.forEach((item) => {
    // 提取日期部分 (YYYY-MM-DD)
    const date = item.dt_txt.split(" ")[0];
    if (!forecastsByDay[date]) {
      forecastsByDay[date] = [];
    }
    forecastsByDay[date].push(item);
  });

  // 为每一天计算最高温度、最低温度和其他数据
  const dailyForecasts: DayForecast[] = Object.keys(forecastsByDay).map(
    (date) => {
      const dayForecasts = forecastsByDay[date];

      // 找出最高和最低温度
      let minTemp = Number.MAX_VALUE;
      let maxTemp = Number.MIN_VALUE;
      let totalHumidity = 0;
      let totalWindSpeed = 0;

      // 收集所有天气状况，以便选择最常见的
      const weatherConditions: Record<string, number> = {};
      const weatherIcons: Record<string, number> = {};

      dayForecasts.forEach((forecast) => {
        // 温度
        minTemp = Math.min(minTemp, forecast.main.temp_min);
        maxTemp = Math.max(maxTemp, forecast.main.temp_max);

        // 湿度和风速
        totalHumidity += forecast.main.humidity;
        totalWindSpeed += forecast.wind.speed;

        // 天气状况
        const condition = forecast.weather[0].main;
        weatherConditions[condition] = (weatherConditions[condition] || 0) + 1;

        // 天气图标
        const icon = forecast.weather[0].icon;
        weatherIcons[icon] = (weatherIcons[icon] || 0) + 1;
      });

      // 计算平均湿度和风速
      const avgHumidity = Math.round(totalHumidity / dayForecasts.length);
      const avgWindSpeed =
        Math.round((totalWindSpeed / dayForecasts.length) * 10) / 10;

      // 找出最常见的天气状况和图标
      let mostCommonCondition = "";
      let maxConditionCount = 0;
      Object.entries(weatherConditions).forEach(([condition, count]) => {
        if (count > maxConditionCount) {
          mostCommonCondition = condition;
          maxConditionCount = count;
        }
      });

      let mostCommonIcon = "";
      let maxIconCount = 0;
      Object.entries(weatherIcons).forEach(([icon, count]) => {
        if (count > maxIconCount) {
          mostCommonIcon = icon;
          maxIconCount = count;
        }
      });

      // 将天气状况翻译为中文
      const conditionMap: Record<string, string> = {
        Clear: "晴天",
        Clouds: "多云",
        Rain: "雨天",
        Drizzle: "小雨",
        Thunderstorm: "雷雨",
        Snow: "雪",
        Mist: "薄雾",
        Smoke: "烟雾",
        Haze: "霾",
        Dust: "尘土",
        Fog: "雾",
        Sand: "沙尘",
        Ash: "火山灰",
        Squall: "暴风",
        Tornado: "龙卷风",
      };

      return {
        date,
        temperature: {
          min: Math.round(minTemp),
          max: Math.round(maxTemp),
        },
        condition: conditionMap[mostCommonCondition] || mostCommonCondition,
        humidity: avgHumidity,
        windSpeed: avgWindSpeed,
        icon: mostCommonIcon,
      };
    }
  );

  console.log("dailyForecasts", dailyForecasts);

  // 只返回最多5天的预报
  return dailyForecasts.slice(0, 6);
}
